import json
import math
import os
import random
import re
import time
import traceback
import execjs
import requests
from tzhhone_downplays.Downloader import Downloader

session = requests.session()
headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/94.0.4606.81 Safari/537.36",
    "referer": "https://www.douyu.com/",
    "sec-ch-ua": '"Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"',
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": '"Windows"',
    "sec-fetch-dest": "document",
    "sec-fetch-mode": "navigate",
    "sec-fetch-site": "same-site",
    "sec-fetch-user": "?1",
    "upgrade-insecure-requests": "1"
}
proxies_q = {
    "http": "127.0.0.1:7890",
    "https": "127.0.0.1:7890"
}


def run_js(play):
    """
    计算sign
    :param play:
    :return:
    """
    t = time.time()
    os.environ["NODE_PATH"] = os.getcwd() + "/node_modules"
    try:
        key = execjs.compile("""
            var CryptoJS = require("crypto-js");
            %s
        """ % play["js"]).call('ub98484234', play["point_id"],
                               '10000000000000000000000000001501', int(t))
        key_arr = re.findall(r'([\S]+)=([\s\S]+)&([\S]+)=([\s\S]+)&([\S]+)=([\s\S]+)&([\S]+)=([\s\S]+)', key)[0]
        i = 0
        ret = {}
        last_item = ""
        for item in key_arr:
            i += 1

            if i % 2 is 0:
                ret[last_item] = item

            else:
                last_item = item
                ret[item] = ""
        return ret
    except:
        traceback.print_exc()
        return None


def get_js(url, proxies={}):
    """
    获取加密js，与json数据
    :param url:
    :param proxies:
    :return:
    """
    try:
        res = session.get(url, headers=headers, proxies=proxies)
        res.encoding = "utf8"
        js = re.findall(r'<script>([\s\S]+?)<\/script>', res.text)

        jscode = r"""
            function getInfo() {
                window = { 
                            "$DATA": {} 
                        };
                        %s
                return JSON.stringify(window);
            };
        """ % js[1]
        json_obj = execjs.compile(jscode)
        json_obj = json_obj.call("getInfo")
        json_obj = json.loads(json_obj)
        plays_info = json_obj["$DATA"]["ROOM"]

        plays_info["js"] = js[2]
        return plays_info
    except:
        traceback.print_exc()
        return None


def get_plays_url(k, play, proxies={}):
    """
    获取视频地址
    :param k:
    :param play:
    :param proxies:
    :return:
    """
    try:
        k["vid"] = play["vid"]
        res = session.post("https://v.douyu.com/api/stream/getStreamUrl", data=k,
                           headers=headers,
                           proxies=proxies)
        res_json = res.json()
        if res_json["error"] == 0:
            plays_url = res_json["data"]["thumb_video"]["high"]["url"]
            return plays_url
        else:
            print("获取视频地址，错误 %s" % res_json)
            return None
    except:
        traceback.print_exc()
        return None


def search_plays(kw="mina", page=1, page_size=20, proxies={}):
    """
    搜索视频目录
    :param kw:
    :param page:
    :param page_size:
    :param proxies:
    :return:
    """
    res = session.get(
        "https://www.douyu.com/japi/search/api/searchVideo?kw=%s&page=%s&pageSize=%s&filterType=1&tabType=1" % (
            kw, page, page_size), headers=headers, proxies=proxies)

    res_json = res.json()
    ret = {"data": [], "total": 0}
    if res_json["error"] == 0:
        ret["total"] = res_json["data"]["total"]
        for item in res_json["data"]["relateVideo"]:
            ret["data"].append(item)
        return ret
    else:
        print("请求失败")
        return None


if __name__ == '__main__':
    try:
        page = 1
        data = search_plays("周淑怡", page=page)
        total = data["total"]
        page_max = math.ceil(total / 20)
        page_zd = 5
        print("当前搜索的条目最大页数：%s" % str(page_max))

        while page < page_zd:

            for item in data["data"]:
                print("开始下载：%s" % item["url"])
                plays = get_js(item["url"])
                key = run_js(plays)
                url = get_plays_url(key, plays)

                print('已经下载到视频:%s' % plays["name"].replace(".", "-").replace(" ", "").replace(":", ""))
                down = Downloader(url, filename='plays/%s-%s.mp4' % (
                    plays["name"].replace(".", "-").replace(" ", "").replace(":", ""),
                    str(random.randint(10000, 99999)))).run(
                    max_workers=5)

                if random.randint(0, 1000) < 700:
                    s = random.randint(5, 12)
                else:
                    s = random.randint(12, 30)
                print("随机休眠:%s" % s)
                time.sleep(s)
            page += 1
            print("开始下载第 %s 页" % str(page))
            data = search_plays(page=page)
    except:
        traceback.print_exc()
        print("当前下载出错，跳过")

